/**
 * 
 */
package t4j.concurrency;

import java.util.concurrent.TimeUnit;

//继承Thread内部类
class InnerThread1 {
	private int countDown = 5;
	private Inner inner;

	private class Inner extends Thread {

		public Inner(String name) {
			super(name);
			start();
		}

		public void run() {
			try {
				while (true) {
					System.out.println(this);

					if (--countDown == 0)
						return;

					sleep(10);
				}

			} catch (InterruptedException e) {
				System.out.println("interrupted");
			}
		}

		public String toString() {
			return getName() + ": " + countDown;
		}
	}

	public InnerThread1(String name) {
		inner = new Inner(name);//创建内部类
	}
}

//继承Thread 的匿名类
class InnerThread2 {
	private int countDown = 5;
	private Thread t;

	public InnerThread2(String name) {
		//实际这是向上转型，因为这个是Thread的子类
		t = new Thread(name) {
			public void run() {
				try {
					while (true) {
						System.out.println(this);
						if (--countDown == 0)
							return;

						sleep(10);
					}

				} catch (InterruptedException e) {
					System.out.println("sleep() interrupted");
				}
			}

			public String toString() {
				return getName() + ": " + countDown;
			}
		};

		t.start();
	}
}

//实现Runnable的内部类
class InnerRunnable1 {
	private int countDown = 5;
	private Inner inner;

	private class Inner implements Runnable {
		Thread t;

		Inner(String name) {
			t = new Thread(this, name);
			t.start();
		}

		public void run() {
			try {
				while (true) {
					System.out.println(this);
					if (--countDown == 0)
						return;
					TimeUnit.MILLISECONDS.sleep(10);
				}

			} catch (InterruptedException e) {
				System.out.print("sleep() interrupted");
			}
		}

		public String toString() {
			return t.getName() + ": " + countDown;
		}
	}
	
	public InnerRunnable1(String name) {
		inner = new Inner(name);
	}
}

//实现Runnable的匿名类
class InnerRunnable2 {
	private int countDown = 5;
	private Thread t;

	public InnerRunnable2(String name) {

		t = new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					while (true) {
						System.out.println(this);
						if (--countDown == 0)
							return;
						TimeUnit.MILLISECONDS.sleep(10);
					}
				} catch (InterruptedException e) {
					System.out.print("sleep() interrupted");
				}
			}

			@Override
			public String toString() {

				return Thread.currentThread().getName() + ": " + countDown;
			}
		}, name);

		t.start();
	}
}
//在方法内部创建线程，如果该类只执行辅助操作，而不是该类的重要操作，这比构造器启动线程更加适合
class ThreadMethod{
	private int countDown = 5;
	private Thread t;
	private String name;
	
	public ThreadMethod(String name) {
		this.name = name;
	}
	
	public void runTask(){
		if(t == null){
			t = new Thread(name){
				public void run(){
					try {
						while(true){
							System.out.println(this);
							if(--countDown == 0) return;
							sleep(10);
						}
						
					} catch (InterruptedException e) {
						System.out.print("sleep() interrupted");
					}
				}
				
				public String toString() { return getName() + ": " + countDown;}
			}; 
			t.start();
		}
	}
}

public class ThreadVariations {
	public static void main(String[] args) {
		new InnerThread1("InnerThread1");
		new InnerThread2("InnerThread2");
		new InnerRunnable1("InnerRunnable1");
		new InnerRunnable2("InnerRunnable2");
		new ThreadMethod("ThreadMethod").runTask();
	}
}
